/**
 * 实现批量登录相关界面逻辑
 */
import { useStreams } from '@/lib/utils'
import services from '@/services'
import { Status } from '@/services/qywxs/batch-login'
import type { Device } from '@/services/qywxs/batch-login'

const { Idle, Queueing, LoggingIn, Failed } = Status

export enum ChooseAllStatus {
  Disable = 1, // 不允许进行全选
  Empty = 2, // 没有被选中的设备
  Partial = 3, // 有一部分设备被选中
  Full = 4, // 全部设备被选中
}

export default function useBatchLogin(
  visible: boolean,
  rawOnClose: (needConfirm: boolean) => void, // needConfirm 为 true 时使用者应自行实现”确认对话框“逻辑，待用户再次确认后才实际自行关闭行为
) {
  const { batchLogin } = useMemo(() => services.qywxs, [])
  const { compareId, compareName, compareStatus } = batchLogin // eslint-disable-line @typescript-eslint/unbound-method

  const [taskStatus, deviceMap] = useStreams(batchLogin.status, batchLogin.devices)

  /**
   * 处理登录流程的启停
   */
  const started = taskStatus.started
  const error = !taskStatus.started ? taskStatus.error : null
  const start = useCallback(() => batchLogin.start(), [])
  const stop = useCallback(() => batchLogin.stop(), [])

  /**
   * 维护设备列表
   */
  const [loading, setLoading] = useState(false)
  const loadDevices = useCallback(async () => {
    setLoading(true)
    await batchLogin.loadDevices()
    setLoading(false)
  }, [])

  const devices = useMemo(() => [...deviceMap.values()], [deviceMap])
  const hasPendingDevice = useMemo(
    () => started && !!devices.find(device => [Queueing, LoggingIn].includes(device.status)),
    [started, devices],
  ) // 是否有正在登录的设备

  /**
   * 处理设备选中状态
   */
  const chooseAble = useCallback(
    (device: Device) => [Queueing, Idle, Failed].includes(device.status),
    [],
  ) // 判断指定设备是否可选

  // “全选”状态
  const chooseAllStatus = useMemo(() => {
    const chooseAbles = devices.filter(chooseAble) // 允许选择的设备列表
    if (!chooseAbles.length) return ChooseAllStatus.Disable // 没有可选的设备，禁用“全选”

    const choosedNum = chooseAbles.filter(device => device.status === Queueing).length
    return choosedNum === 0
      ? ChooseAllStatus.Empty
      : choosedNum < chooseAbles.length
      ? ChooseAllStatus.Partial
      : ChooseAllStatus.Full
  }, [devices, chooseAble])

  const chooseAll = useCallback(() => batchLogin.chooseAll(), []) // 执行全选
  const choose = useCallback((device: Device) => batchLogin.choose(device.id), []) // 切换指定设备选择状态（Failed 的设备也可以调用）

  /**
   * 处理界面显隐相关逻辑
   */
  const onClose = useCallback(() => rawOnClose(hasPendingDevice), [hasPendingDevice, rawOnClose]) // 触发“关闭界面”行为时，调用此回调
  useEffect(() => {
    if (visible) void loadDevices() // 界面显示时加载设备列表
    else batchLogin.stop() // 界面隐藏时结束登录行为
  }, [visible, loadDevices])

  return {
    started,
    error,
    start,
    stop,
    loading,
    loadDevices,
    devices,
    chooseAble,
    chooseAllStatus,
    chooseAll,
    choose,
    onClose,
    compareId,
    compareName,
    compareStatus,
  }
}
